package digitrencer;



import java.util.ArrayList;
//import java.util.HashMap;

/**
 * A program funkcióit magába foglaló osztály. Rajta keresztül hajtható végre az összes, a hálózat működésével kapcsolatos utasítás.
 * @author Gergő
 */
public class Model {
        private ArrayList<Wire> wireList = new ArrayList<Wire>();
	private ArrayList<Element> elementList = new ArrayList<Element>();
	//Ezeket a szkeleton felépítéséből fakadólag nem használjuk, de a végleges programban fogjuk.
        //private HashMap<Integer, Output> outputList = new HashMap();
	//private HashMap<Integer, Switch> switchList = new HashMap();
	//private HashMap<Integer, Generator> generatorList = new HashMap();

    /**
     * A hálózatban lévő generátort tartalmazó változó (a tesztesetekben max 1 generátor szerepel). Külön kívülről kell beállítani.
     */
    public Generator generator; 
    /**
     * A teszteset sorszámát tartalmazó változó, melyet a konstruktorban kell beállítani.
     */
    public int teszt;

        /**
         * A Model osztály konstruktora.
         * @param test A teszteset sorszáma, mely egy int formátumú egész szám.
         */
        public Model(int test) {
            System.out.println("CREATE | #0:Model | Model(int test = " + test + ")");
            teszt=test;
        }
	

        /**
         * A hálózat frissítésére szolgáló függvény. Meghívja az alkatrészek run() függvényét, majd a vezetékek refresh() függvényét a tesztesettől függő alkalomszor.
         */
        public void refresh() {
                System.out.println("CALL | #0:Model | void refresh()");
		int iter;
                switch (teszt){
                    case 1: {iter = 2; break;}
                    case 2: {iter = 3; break;}
                    case 3: {iter = 4; break;}
                    case 4: {iter = 3; break;}
                    case 5: {iter = 3; break;}
                    default: iter =3;
                }
                for (int i = 0; i < iter; i++) {
                    for(Element element : elementList) element.run();
                    for(Wire wire : wireList) wire.refresh();
                }
	}

        /**
         * Egy elem hálózathoz való hozzáadására szolgáló függvény.  A kapott elemet beteszi a megfelelő listába.
         * @param element A hozzáadandó alkatrész, ami Element formátumú.
         */
        public void addElement(Element element) {
		System.out.println("CALL | #0:Model | void addElement(Element element = Element#" + element.id + ")");
        elementList.add(element);

	}

    /**
     * A kapott Output típusú alkatrész értékét visszaadó  függvény.
     * @param output Az az Output típusú alkatrész, aminek az értékét le akarjuk kérdezni.
     * @return A paraméterként kapott alkatrész értéke boolean formában.
     */
    public boolean getOutputValue(Output output) {
        System.out.println("CALL | #0:Model | boolean getOutputValue(Output output = Output#" + output.id + ")");
		boolean val = output.getValue();
        System.out.println("RETURN | #0:Model | boolean val = " + val);
        return val;
	}

    /**
     * A hálózat generátorainak léptetésére szolgáló függvény.
     */
    public void stepGenerators() {
        System.out.println("CALL | #0:Model | void stepGenerators()");
		generator.step();
	}

    /**
     * Egy kapcsoló értékének ellenkezőre állítására szolgáló függvény.
     * @param sw Az átállítandó Switch formátumú kapcsoló.
     */
    public void setSwitch(Switch sw) {
        System.out.println("CALL | #0:Model | void setSwitch(Switch sw = Switch#" + sw.id + ")");
		sw.setSwitch();
	}

    /**
     * Egy jelgenerátor szekvenciájának beállítására szolgáló fügvény.
     * @param gen Az átállítandó Generator formátumú generátor.
     * @param seq A beállítani kívánt szekvencia, egy String formátumú 01-sorozat.
     */
    public void setSequence(Generator gen, String seq) {
        System.out.println("CALL | #0:Model | void setSequence(Generator gen = Generator#" + gen.id + ", String seq = \"" + seq + "\")");
		gen.setSeq(seq);
	}

    /**
     * Egy jelgenerátor szekvenciájának lekérdezésére szolgáló függvény.
     * @param gen A lekérdezni kívánt generátor, ami Generator formátumú.
     * @return A generátor szekvenciája, ami egy String formátumú 01-sorozat.
     */
    public String getSequence(Generator gen) {
        System.out.println("CALL | #0:Model | String getSequence(Generator gen = Generator#" + gen.id + ")");
        String seq = gen.getSeq();
        System.out.println("RETURN | #0:Model | String seq = \"" + seq + "\"");
        return seq;
	}

    /**
     * Egy vezeték hálózathoz való hozzáadására szolgáló függvény.  A kapott vezetéket beteszi a vezetékek listájába.
     * @param wire A hozzáadandó vezeték, ami Wire formátumú.
     */
    public void addWire(Wire wire) {
		System.out.println("CALL | #0:Model | void addWire(Wire wire = Wire#" + wire.id + ")");
        wireList.add(wire);
	}

    /**
     * A kapott Input típusú alkatrész kimeneti értékét visszaadó  függvény.
     * @param input Az az Input típusú alkatrész, aminek a kimenetét le akarjuk kérdezni.
     * @return A paraméterként kapott alkatrész kimeneti értéke boolean formában.
     */
    public boolean getInputValue(Input input) {
		System.out.println("CALL | #0:Model | void getInputValue(Input input = Input#" + input.id + ")");
        boolean val = input.getValue();
        System.out.println("RETURN | #0:Model | boolean val = " + val);
        return val;
	}

    /**
     * A hálózat alapállapotba állítására szolgáló függvény.
     */
    public void reset() {
        System.out.println("CALL | #0:Model | void reset()");
		for(Wire wire : wireList) {wire.setStart(false); wire.refresh();}
        generator.reset();
	}
}